console.log(typeof 1); //number
console.log(typeof "1"); //string
console.log(typeof true); //boolean
console.log(typeof undefined); //undefined
console.log(typeof null); //object   注意,这里是一个历史bug
console.log(typeof 123n); //bigint
console.log(typeof Symbol("foo")); //symbol

console.log(typeof {}); //object
console.log(typeof []); // object
console.log(typeof function () {}); //function

// typeof的缺陷演示
console.log("\n// typeof的缺陷演示");
console.log("typeof null:", typeof null); // 输出 "object"，这是JS的历史bug
console.log("typeof []:", typeof []); // 输出 "object"，无法区分数组和普通对象
console.log("typeof {}:", typeof {}); // 输出 "object"
console.log("typeof new Date():", typeof new Date()); // 输出 "object"
console.log("typeof /regex/:", typeof /regex/); // 输出 "object"

// 解决方案和最佳实践
console.log("\n// 解决方案和最佳实践");
// 1. 判断null使用严格等于
const value = null;
console.log("value === null:", value === null); // true

// 2. 判断数组使用Array.isArray()
const arr = [1, 2, 3];
const obj = { a: 1, b: 2 };
console.log("Array.isArray(arr):", Array.isArray(arr)); // true
console.log("Array.isArray(obj):", Array.isArray(obj)); // false

// 类型判断的终极武器：Object.prototype.toString.call()
console.log("\n// 类型判断的终极武器");
console.log("Object.prototype.toString.call(1):", Object.prototype.toString.call(1)); // [object Number]
console.log("Object.prototype.toString.call('1'):", Object.prototype.toString.call('1')); // [object String]
console.log("Object.prototype.toString.call(true):", Object.prototype.toString.call(true)); // [object Boolean]
console.log("Object.prototype.toString.call(undefined):", Object.prototype.toString.call(undefined)); // [object Undefined]
console.log("Object.prototype.toString.call(null):", Object.prototype.toString.call(null)); // [object Null]
console.log("Object.prototype.toString.call({}):", Object.prototype.toString.call({})); // [object Object]
console.log("Object.prototype.toString.call([]):", Object.prototype.toString.call([])); // [object Array]
console.log("Object.prototype.toString.call(function(){}):", Object.prototype.toString.call(function(){})); // [object Function]
console.log("Object.prototype.toString.call(new Date()):", Object.prototype.toString.call(new Date())); // [object Date]
console.log("Object.prototype.toString.call(/regex/):", Object.prototype.toString.call(/regex/)); // [object RegExp]
